package com.plian.system.config;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.StringUtil;
import com.plian.system.entity.fr.bank.BankKey;
import com.plian.system.model.R;
import com.plian.system.service.fr.bank.IBankKeyService;
import com.plian.system.vo.fr.bank.AppSignVO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.time.Duration;
import java.util.Date;

@Aspect
@Component
public class AppKeySignAspect {

    @Autowired
    private IBankKeyService bankKeyService;

    /**
     * 时间差最小值
     */
    private final static Integer SECOND_MIN = 0;

    /**
     * 时间差最大值
     */
    private final static Integer SECOND_MAX = 6000;

    @Around("@annotation(com.plian.system.config.AppKeySign)")
    public Object handleAppKey(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] pointArgs = joinPoint.getArgs();
        AppSignVO appSignVO = (AppSignVO) pointArgs[0];
        if (appSignVO == null){
            return R.fail("签名信息为空！");
        }
        String appId = appSignVO.getAppId();
        if (StringUtil.isBlank(appId)){
            return R.fail("appId为空！");
        }
        if (StringUtil.isBlank(appSignVO.getToken())){
            return R.fail("token为空！");
        }
        if (appSignVO.getTimestamp() == null){
            return R.fail("请求时间戳非法！");
        }
        long seconds = 0L;
        if (appSignVO.getTimestamp() > 10000000000L){
            //毫秒
            seconds = Duration.between(new Date(appSignVO.getTimestamp()).toInstant(), new Date().toInstant()).getSeconds();
        }else {
            //秒
            seconds = new Date().getTime()/1000 - appSignVO.getTimestamp();
        }
        if (seconds < SECOND_MIN || seconds > SECOND_MAX) {
            return R.fail("请求时间戳非法！");
        }
        BankKey bankKey = bankKeyService.getOne(Wrappers.<BankKey>lambdaQuery().eq(BankKey::getAppId, appId));
        if (bankKey == null){
            return R.fail("appId不存在！");
        }
        String key = bankKey.getBankKey();
        String str = key + appId + appSignVO.getTimestamp();

        if (!appSignVO.getToken().equals(DigestUtils.md5DigestAsHex(str.getBytes()))){
            return R.fail("token不合法！");
        }
        return joinPoint.proceed();
    }

    public String checkAppSign(AppSignVO appSignVO){
        if (appSignVO == null){
            return "签名信息为空！";
        }
        String appId = appSignVO.getAppId();
        if (StringUtil.isBlank(appId)){
            return "appId为空！";
        }
        if (StringUtil.isBlank(appSignVO.getToken())){
            return "token为空！";
        }
        if (appSignVO.getTimestamp() == null){
            return "请求时间戳非法！";
        }
        long seconds = 0L;
        if (appSignVO.getTimestamp() > 10000000000L){
            //毫秒
            seconds = Duration.between(new Date(appSignVO.getTimestamp()).toInstant(), new Date().toInstant()).getSeconds();
        }else {
            //秒
            seconds = new Date().getTime()/1000 - appSignVO.getTimestamp();
        }
        if (seconds < SECOND_MIN || seconds > SECOND_MAX) {
            return "请求时间戳非法！";
        }
        BankKey bankKey = bankKeyService.getOne(Wrappers.<BankKey>lambdaQuery().eq(BankKey::getAppId, appId));
        if (bankKey == null){
            return "appId不存在！";
        }
        String key = bankKey.getBankKey();
        String str = key + appId + appSignVO.getTimestamp();

        if (!appSignVO.getToken().equals(org.springframework.util.DigestUtils.md5DigestAsHex(str.getBytes()))){
            return "token不合法！";
        }
        return null;
    }
}
